package asteroids.entity.equipment;

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;

import org.apache.log4j.Logger;

import asteroids.engine.GameState;
import asteroids.engine.Utils;
import asteroids.entity.GameObject;
import asteroids.entity.Ship;
import asteroids.factory.ShapeLib;

/**
 * add this to a ship via equip() to make it auto-regen, using the ship's energy
 * reserves add this using setSpecial to make it regenerate only when the pilot
 * uses Pilot.SPECIAL
 * 
 * @author whitecd1
 * 
 */
public class RegeneratingShield extends Equipment
{
    private static final Logger logger = Logger.getLogger(RegeneratingShield.class);

    private final int SHIELDING_TIME = (int) (0.8 * Utils.FRAMES_PER_SECOND);
    private int shielding = 0;

    private int prior_x;
    private int prior_y;

    private double maxPower;
    private double currentPower;
    private double energyDraw;
    private double energyDrawInterval;
    private long lastEnergyDrawTime = 0;

    public RegeneratingShield(Ship ship, int maxPower, double energyDraw, double drawInterval)
    {
        super(ship);
        max_radius = ShapeLib.shipLength;
        this.maxPower = maxPower;
        currentPower = maxPower;
        this.energyDraw = energyDraw;
        this.energyDrawInterval = drawInterval;
    }

    public RegeneratingShield(Ship ship, int maxPower)
    {
        this(ship, maxPower, 0.5, Utils.FRAMES_PER_SECOND / 2d);
    }

    @Override
    public void update(GameState state)
    {
        shielding = (shielding > 0) ? shielding - 1 : shielding;

        if( currentPower < maxPower
                && state.currentGameTime() - lastEnergyDrawTime >= energyDrawInterval
                && ship.getEnergy() > energyDraw )
        {
            lastEnergyDrawTime = state.currentGameTime();
            ship.modifyEnergyBy(energyDraw);
            currentPower = Math.min(energyDraw + currentPower, maxPower);
        }

        if( currentPower > 0 ) // shield is active
        {
            ship.makeInvincible();
            // check for Bad Things!
            ArrayList<GameObject> possibleTargets = new ArrayList<GameObject>();
            possibleTargets.addAll(state.getAsteroidManager().getObjects()); // include
                                                                             // all
                                                                             // asteroids

            for( Ship s : state.getShipManager().getObjects() )
            {
                possibleTargets.add(s); // add all ships
                possibleTargets.addAll(s.getObjects()); // add all Bullets
            }
            for( GameObject other : possibleTargets )
            {
                // if the ship is being hit by something that will hurt it
                if( Utils.gameObjectsCollide(ship, other) && other.isAlive()
                        && other.getAffiliation() != ship.getAffiliation()
                        && ship.getRespawnTimeLeft() == 0 && other.getCollisionPower(ship) > 0 )
                {
                    logger.trace("shield colliding for " + other.getCollisionPower(ship));
                    shielding = SHIELDING_TIME;
                    // modify shield integrity
                    this.collide(other, other.getCollisionPower(ship));
                    // hit back just as hard
                    other.collide(this, other.getCollisionPower(ship));

                    // push the other thing away
                    // other.push(Utils.pointDirection(ship.getXPosition(),
                    // ship.getYPosition(), other.getXPosition(),
                    // other.getYPosition()), force);
                }
            }
        }
    }

    @Override
    public void respawn()
    {
        currentPower = maxPower;
    }

    @Override
    // prevents this object from being destroy()-ed when hit
    // also keeps correct track of the amount of power left.
    public void damage(double amt)
    {
        currentPower = Math.max(currentPower - amt, 0);
    }

    public void draw(Graphics g)
    {
        float col = (float) Math.max(((currentPower / maxPower)), .1);

        if( shielding > 1 && ship.isAlive() ) // slight buffer so it erases
        {
            g.setColor(new Color(col, col, col));
            prior_x = (int) (ship.getXPosition() - max_radius);
            prior_y = (int) (ship.getYPosition() - max_radius);
            g.drawOval(prior_x, prior_y, (int) (max_radius * 2), (int) (max_radius * 2));
        }
    }
}
